using WeatherSystem.API.Models;
using WeatherSystem.API.Specifications;
using WeatherSystem.API.Extensions;

namespace WeatherSystem.API.Repositories
{
    /// <summary>
    /// 天气数据Repository旧接口适配器
    /// 用于向后兼容新的读写分离架构
    /// </summary>
    public class LegacyWeatherDataAdapter : IWeatherDataRepository
    {
        private readonly IWeatherDataReadRepository _readRepository;
        private readonly IWeatherDataWriteRepository _writeRepository;

        public LegacyWeatherDataAdapter(IWeatherDataReadRepository readRepository, IWeatherDataWriteRepository writeRepository)
        {
            _readRepository = readRepository;
            _writeRepository = writeRepository;
        }

        public async Task<WeatherDataEntry?> GetLatestByCityAsync(Guid cityId)
        {
            return await _readRepository.GetLatestByCityAsync(cityId);
        }

        public async Task<List<WeatherDataEntry>> GetHistoryAsync(Guid cityId, DateTime startDate, DateTime endDate)
        {
            var result = await _readRepository.GetHistoryAsync(cityId, startDate, endDate);
            return result.ToList();
        }

        public async Task<PagedResult<Dictionary<string, object>>> GetWeatherDataPagedAsync(
            int page, int pageSize, Guid? cityId = null,
            DateTime? startDate = null, DateTime? endDate = null,
            string? source = null, string? sortBy = null, string? sortDirection = null)
        {
            return await _readRepository.GetWeatherDataPagedAsync(
                page, pageSize, cityId, startDate, endDate, source, sortBy, sortDirection);
        }

        public async Task<List<WeatherDataEntry>> GetByCityAndDateRangeAsync(Guid cityId, DateTime startDate, DateTime endDate)
        {
            var spec = new WeatherDataWithCitySpecification(cityId, startDate, endDate, null);
            var result = await _readRepository.GetBySpecificationAsync(spec);
            return result.ToList();
        }

        public async Task<Dictionary<string, object>> GetWeatherDataAsDictionaryAsync(Guid entryId)
        {
            var entry = await _readRepository.GetByIdAsync(entryId);
            return entry?.ToDictionary() ?? new Dictionary<string, object>();
        }

        public async Task<List<Dictionary<string, object>>> GetWeatherHistoryAsDictionaryAsync(Guid cityId, DateTime startDate, DateTime endDate)
        {
            var spec = new WeatherDataWithCitySpecification(cityId, startDate, endDate, null);
            var result = await _readRepository.GetBySpecificationAsync(spec);
            return result.Select(e => e.ToDictionary()).ToList();
        }

        // 实现基础接口方法
        public async Task<WeatherDataEntry?> GetByIdAsync(Guid id)
        {
            return await _readRepository.GetByIdAsync(id);
        }

        public async Task<IEnumerable<WeatherDataEntry>> GetAllAsync()
        {
            var result = await _readRepository.GetAllAsync();
            return result.ToList();
        }

        public async Task<IEnumerable<WeatherDataEntry>> FindAsync(System.Linq.Expressions.Expression<Func<WeatherDataEntry, bool>> predicate)
        {
            // IReadRepository doesn't have FindAsync, need to create a specification
            var spec = new WeatherDataSpecification(predicate);
            var result = await _readRepository.GetBySpecificationAsync(spec);
            return result.ToList();
        }

        public async Task AddAsync(WeatherDataEntry entity)
        {
            await _writeRepository.AddAsync(entity);
        }

        public async Task AddRangeAsync(IEnumerable<WeatherDataEntry> entities)
        {
            await _writeRepository.AddRangeAsync(entities);
        }

        public async Task UpdateAsync(WeatherDataEntry entity)
        {
            await _writeRepository.UpdateAsync(entity);
        }

        public async Task UpdateRangeAsync(IEnumerable<WeatherDataEntry> entities)
        {
            await _writeRepository.UpdateRangeAsync(entities);
        }

        public async Task DeleteAsync(WeatherDataEntry entity)
        {
            await _writeRepository.DeleteAsync(entity);
        }

        public async Task DeleteRangeAsync(IEnumerable<WeatherDataEntry> entities)
        {
            await _writeRepository.DeleteRangeAsync(entities);
        }

        public async Task<int> CountAsync(System.Linq.Expressions.Expression<Func<WeatherDataEntry, bool>>? predicate = null)
        {
            var spec = predicate != null ? new WeatherDataSpecification(predicate) : null;
            return await _readRepository.CountAsync(spec);
        }

        // 实现IReadRepository接口的新方法
        public async Task<WeatherDataEntry?> GetByIdAsync(Guid id, CancellationToken cancellationToken = default)
        {
            return await _readRepository.GetByIdAsync(id, cancellationToken);
        }

        public async Task<IEnumerable<WeatherDataEntry>> GetAllAsync(CancellationToken cancellationToken = default)
        {
            var result = await _readRepository.GetAllAsync(cancellationToken);
            return result.ToList();
        }

        public async Task<IEnumerable<WeatherDataEntry>> GetBySpecificationAsync(ISpecification<WeatherDataEntry> specification, CancellationToken cancellationToken = default)
        {
            var result = await _readRepository.GetBySpecificationAsync(specification, cancellationToken);
            return result.ToList();
        }

        public async Task<WeatherDataEntry?> GetSingleBySpecificationAsync(ISpecification<WeatherDataEntry> specification, CancellationToken cancellationToken = default)
        {
            return await _readRepository.GetSingleBySpecificationAsync(specification, cancellationToken);
        }

        public async Task<int> CountAsync(ISpecification<WeatherDataEntry>? specification = null, CancellationToken cancellationToken = default)
        {
            return await _readRepository.CountAsync(specification, cancellationToken);
        }

        public async Task<bool> AnyAsync(ISpecification<WeatherDataEntry>? specification = null, CancellationToken cancellationToken = default)
        {
            return await _readRepository.AnyAsync(specification, cancellationToken);
        }

        public async Task<PagedResult<WeatherDataEntry>> GetPagedAsync(int page, int pageSize, ISpecification<WeatherDataEntry>? specification = null, CancellationToken cancellationToken = default)
        {
            return await _readRepository.GetPagedAsync(page, pageSize, specification, cancellationToken);
        }

        public async Task<IEnumerable<TResult>> GetProjectedAsync<TResult>(System.Linq.Expressions.Expression<Func<WeatherDataEntry, TResult>> projection, ISpecification<WeatherDataEntry>? specification = null, CancellationToken cancellationToken = default)
        {
            var result = await _readRepository.GetProjectedAsync(projection, specification, cancellationToken);
            return result.ToList();
        }

        public async Task<PagedResult<TResult>> GetProjectedPagedAsync<TResult>(System.Linq.Expressions.Expression<Func<WeatherDataEntry, TResult>> projection, int page, int pageSize, ISpecification<WeatherDataEntry>? specification = null, CancellationToken cancellationToken = default)
        {
            return await _readRepository.GetProjectedPagedAsync(projection, page, pageSize, specification, cancellationToken);
        }

        // 实现IWriteRepository接口的新方法
        public async Task<WeatherDataEntry> AddAsync(WeatherDataEntry entity, CancellationToken cancellationToken = default)
        {
            return await _writeRepository.AddAsync(entity, cancellationToken);
        }

        public async Task<IEnumerable<WeatherDataEntry>> AddRangeAsync(IEnumerable<WeatherDataEntry> entities, CancellationToken cancellationToken = default)
        {
            var result = await _writeRepository.AddRangeAsync(entities, cancellationToken);
            return result.ToList();
        }

        public async Task UpdateAsync(WeatherDataEntry entity, CancellationToken cancellationToken = default)
        {
            await _writeRepository.UpdateAsync(entity, cancellationToken);
        }

        public async Task UpdateRangeAsync(IEnumerable<WeatherDataEntry> entities, CancellationToken cancellationToken = default)
        {
            await _writeRepository.UpdateRangeAsync(entities, cancellationToken);
        }

        public async Task DeleteAsync(WeatherDataEntry entity, CancellationToken cancellationToken = default)
        {
            await _writeRepository.DeleteAsync(entity, cancellationToken);
        }

        public async Task DeleteAsync(Guid id, CancellationToken cancellationToken = default)
        {
            await _writeRepository.DeleteAsync(id, cancellationToken);
        }

        public async Task DeleteRangeAsync(IEnumerable<WeatherDataEntry> entities, CancellationToken cancellationToken = default)
        {
            await _writeRepository.DeleteRangeAsync(entities, cancellationToken);
        }

        public async Task<int> SaveChangesAsync(CancellationToken cancellationToken = default)
        {
            return await _writeRepository.SaveChangesAsync(cancellationToken);
        }
    }
}